using System;
using System.Linq;
using System.Reflection;
using System.Text;
using EPiServer.Core;

namespace EPiSugar.EntityAdapter.PropertyBinders
{
    public class LazyChildBinder : IPropertyBinder
    {
        private readonly IPageSource pageSource;
        public PropertyInfo DestinationProperty { get; set; }
        public ConstructorInfo ListConstructor { get; set; }

        public LazyChildBinder(PropertyInfo destinationProperty, IPageSource pageSource)
        {
            this.pageSource = pageSource;
            DestinationProperty = destinationProperty;
            Type[] genericArguments = destinationProperty.PropertyType.GetGenericArguments();
            if (genericArguments.Length != 1)
                throw new ArgumentException("The property '" + destinationProperty.Name + "' has wrong number of generic arguments. Can only bind to generic enumerations or lists, e.g. IList<MyEntityType>", "destinationProperty");

            Type listType = typeof (LazyChildList<>).MakeGenericType(genericArguments);
            if(!destinationProperty.PropertyType.IsAssignableFrom(listType))
                throw new ArgumentException("The property '" + destinationProperty.Name + "' is does not derive from IEnumerable<T>. Try using something like IList<MyEntityType>.", "destinationProperty");

            ListConstructor = listType.GetConstructor(new[] {typeof (PageReference), typeof(IPageSource)});
        }

        public void Bind(PageData sourcePage, object toInstance)
        {
            DestinationProperty.SetValue(toInstance, ListConstructor.Invoke(new object[] { sourcePage.PageLink, pageSource }), null);
        }

        public override string ToString()
        {
            return "Children->" + DestinationProperty.Name;
        }
    }
}
